﻿
#include "picturetcpclient.h"
#include "ui_picturetcpclient.h"
#pragma execution_character_set("utf-8")

PictureTcpClient::PictureTcpClient(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::PictureTcpClient)
{
    ui->setupUi(this);
    this->setWindowIcon(QIcon(":/1.ico"));
    this->setWindowTitle("图片网络传输工具(客户端)");
    this->ChangeEnable(false);
    this->InitTcp();
}

PictureTcpClient::~PictureTcpClient()
{
    delete ui;
}

void PictureTcpClient::InitTcp()
{
    m_tcpClient = new QTcpSocket(this);
    m_tcpClient->abort();               //中断已有的链接
    connect(m_tcpClient,SIGNAL(readyRead()),this,SLOT(ReadData()));
    connect(m_tcpClient,SIGNAL(error(QAbstractSocket::SocketError)),\
            this,SLOT(DisplayError(QAbstractSocket::SocketError)));

    //该信号在调用connectToHost()并成功建立连接之后发出。
    connect(m_tcpClient, SIGNAL(connected()),this, SLOT(conSuc()));
}

void PictureTcpClient::ChangeEnable(bool isEnable)
{
    ui->btnConnect->setEnabled(!isEnable);
    ui->btnDisConnect->setEnabled(isEnable);
    ui->btnSend->setEnabled(isEnable);
    ui->btnSendImg->setEnabled(isEnable);
}

//连接服务器
void PictureTcpClient::ConnectToServer()
{
    m_tcpClient->abort();
    m_tcpClient->connectToHost(ui->txtIP->text(),ui->txtPort->text().toInt());
}

//连接成功
void PictureTcpClient::conSuc()
{
    ui->labInfo->setText("提示:连接成功");
    this->ChangeEnable(true);
}

//发送数据
void PictureTcpClient::SendData()
{
    // 获取 QTextEdit 中的纯文本内容,转换为Latin-1单字节编码的字节数组
    m_tcpClient->write(ui->txtSendData->toPlainText().toUtf8());
}

//读取数据
void PictureTcpClient::ReadData()
{
    QByteArray read=m_tcpClient->readAll();
    if (!read.isEmpty())
    {
        ui->txtGetData->append(QString::fromUtf8(read));
    }
}

void PictureTcpClient::DisplayError(QAbstractSocket::SocketError)
{
    ui->labInfo->setText(QString("提示:连接失败,原因(%1)").arg(m_tcpClient->errorString()));
    this->ChangeEnable(false);
}

//获取打开对话框中指定格式的文件列表
QStringList PictureTcpClient::GetFileNames(QString filter)
{
    QStringList fileNames;
    fileNames=QFileDialog::getOpenFileNames(this,"选择文件",QCoreApplication::applicationDirPath(),filter);
    if (fileNames.isEmpty())
    {
        return QStringList();
    }
    else
    {
        return fileNames;
    }
}

//延时等待功能
void PictureTcpClient::DelayTime(int ms)
{
    QTime t=QTime::currentTime().addMSecs(ms);//当前时间的基础上增加ms毫秒,得到一个目标时间点t
    while(QTime::currentTime()<t)
    {/*处理当前线程的事件队列，并等待最多100毫秒来接收新的事件。
      *处理所有类型的事件，包括定时器事件、绘图事件等
      *通过不断处理事件，可以确保程序在等待期间仍然能够响应其他事件，以避免程序无响应或阻塞*/
        QCoreApplication::processEvents(QEventLoop::AllEvents,100);
    }
}

QByteArray PictureTcpClient::GetPicData(QString fromPic)
{
    QImage img(fromPic);
    // 保存图像数据到 QByteArray
    QByteArray ba;
    QBuffer buf(&ba);
    buf.open(QIODevice::WriteOnly);
    img.save(&buf,"JPG");               //按照JPG解码保存数据
    buf.close();

    QByteArray cc=qCompress(ba,1);      // 对图像数据进行压缩

    QByteArray hh;
    hh=cc.toBase64();                   //获取Base64数据
    return hh;
}


void PictureTcpClient::on_btnConnect_clicked()
{
    this->ConnectToServer();
}


void PictureTcpClient::on_btnDisConnect_clicked()
{
    m_tcpClient->disconnectFromHost();      //断开QTcpSocket对象与远程主机的连接的函数
    ui->labInfo->setText(tr("提示:断开连接"));
    this->ChangeEnable(false);
}


void PictureTcpClient::on_btnSend_clicked()
{
    this->SendData();
}


void PictureTcpClient::on_btnSelectImg_clicked()
{
   ui->listWidget->addItems(this->GetFileNames("图片文件(*.jpg)"));
}


void PictureTcpClient::on_btnClear_clicked()
{
   if (ui->listWidget->count()>0)
        ui->listWidget->clear();
}


void PictureTcpClient::on_btnSendImg_clicked()
{
   if (ui->listWidget->count()<=0)                      //没有图片发送则返回
        return;
   QListWidgetItem *myitem;
   int intervalTime=ui->txtTime->text().toInt();
   qDebug()<<"图片 ="<<ui->listWidget->count();
   for (int i=0;i<ui->listWidget->count();i++)
   {
        qDebug()<<"i="<<i;
        myitem=ui->listWidget->item(i);
        QByteArray myPicData=this->GetPicData(myitem->text());
        if (ui->rbtnJY->isChecked())                    //数据校验
        {
            QByteArray ba;
            QDataStream out(&ba,QIODevice::WriteOnly);  //使用数据流写入数据
            out.setVersion(QDataStream::Qt_4_7);        //设置数据流版本，客户端和服务器端使用版本要相同
            /*预留两个字节的空间来存放文件大小信息
             * 将0的quint16类型的数据写入到数据流中*/
            out<<(quint16)0;                            //放置文件大小信息
            out<<myPicData;                             //将实际的文件数据写入到数据流中
            out.device()->seek(0);                      //将数据流的位置指针移动到起始位置。可以在起始位置再次写入文件大小信息
            /*文件数据的大小减去预留的两个字节后的值*/
            out<<(quint16)(ba.size()-sizeof(quint16));  //将实际的文件大小信息写入到数据流中
            myPicData.clear();
            myPicData=ba;
        }
        m_tcpClient->write(myPicData);
        this->DelayTime(intervalTime);
   }
    QMessageBox::information(this,"提示","恭喜你！发送图片完成！");
}

